/*
 * Copyright (c) 2023, mdf Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2023-10-20     MacRsh       First version
 */

#ifndef MDF_UART_H
#define MDF_UART_H

#include "inc/mdf_api.h"

#if (MDF_CFG_UART == MDF_CFG_ENABLE)

/**
 * @def Uart data bits
 */
#define MDF_UART_DATA_BITS_5            5
#define MDF_UART_DATA_BITS_6            6
#define MDF_UART_DATA_BITS_7            7
#define MDF_UART_DATA_BITS_8            8
#define MDF_UART_DATA_BITS_9            9

/**
 * @def Uart stop bits
 */
#define MDF_UART_STOP_BITS_1            1
#define MDF_UART_STOP_BITS_2            2
#define MDF_UART_STOP_BITS_3            3
#define MDF_UART_STOP_BITS_4            4

/**
 * @def Uart parity
 */
#define MDF_UART_PARITY_NONE            0
#define MDF_UART_PARITY_EVEN            1
#define MDF_UART_PARITY_ODD             2

/**
 * @def Uart bit order
 */
#define MDF_UART_BIT_ORDER_LSB          0
#define MDF_UART_BIT_ORDER_MSB          1

/**
 * @def Uart invert
 */
#define MDF_UART_NRZ_NORMAL             0
#define MDF_UART_NRZ_INVERTED           1

#define MDF_UART_CONFIG_DEFAULT         \
{                                       \
    115200,                             \
    MDF_UART_DATA_BITS_8,               \
    MDF_UART_STOP_BITS_1,               \
    MDF_UART_PARITY_NONE,               \
    MDF_UART_BIT_ORDER_LSB,             \
    MDF_UART_NRZ_NORMAL,                \
}

struct mdf_uart_config
{
    uint32_t baud_rate;
    uint32_t data_bits: 4;
    uint32_t stop_bits: 3;
    uint32_t parity: 2;
    uint32_t bit_order: 1;
    uint32_t invert: 1;
    uint32_t reserved: 21;
};

struct mdf_uart;

struct mdf_uart_ops
{
    int (*configure)(struct mdf_uart *uart, struct mdf_uart_config *config);
    ssize_t (*write)(struct mdf_uart *uart, const void *buf, size_t size);
    ssize_t (*read)(struct mdf_uart *uart, void *buf, size_t size);
    void (*start_tx)(struct mdf_uart *uart);
    void (*stop_tx)(struct mdf_uart *uart);
};

struct mdf_uart
{
    struct mdf_dev dev;

    struct mdf_uart_config config;
    struct mdf_ringbuf rd_fifo;
    struct mdf_ringbuf wr_fifo;
};

int mdf_uart_register(struct mdf_uart *uart, const char *name, struct mdf_drv *drv);

#endif /* MDF_CFG_UART */

#endif /* MDF_UART_H */
